package BNS.graphs;

import java.io.File;
import java.util.Enumeration;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.JFrame;

import BNS.plumbing.Library;


/** Used to create and store GraphPack objects in files.
	Since the layout process is so labour intensive and persnicketty, it cannot be
	done during the experimental session. We build these things ahead of time.
	This class provides GUI support for their creation.
	*/
public class GraphPackBuilder {
	
	public GraphPackBuilder(String fname, int chroma, int maxISsize) {
//		Library.init();
		/* This method must be called before using the Library. It initializes a 
		FileChooser using the PREP property for the storage and retrieval of games.*/
		String prep= System.getProperty("PREP");
		if (prep==null) prep= "./";
		Library.setPrep(new File(prep));
		
		String pack= new File(fname).getName();
//			System.err.println("gpack suffix found at "+ pack.indexOf(".gpack"));
		int sufidx= pack.indexOf(".matrix");
		if (sufidx<1) sufidx= pack.length();
		String pname= pack.substring(0,sufidx);
		Pattern pattern = Pattern.compile("c=\\d*");
		Matcher matcher = pattern.matcher(pname);
		if (matcher.find()) {
			int st= matcher.start();
			int nd= matcher.end();
			String cpull= fname.substring(st+2,nd);
			int colorNum= Integer.parseInt(cpull);
			//System.err.format("matched (%d,%d) found %s%n",st,nd,cpull);
			System.err.println("chromatic number found "+ chroma);
			if (colorNum>2) chroma= colorNum;
			}
		makeAndSave(fname,chroma,maxISsize,pname,1);
		}
	
	private void makeAndSave(String fname, int chroma, int maxISsize, String pname, int type) {
		JFrame frame= new JFrame("GraphPack Creation");
		frame.setSize(600,600);
		Creator crPanel= new Creator();
		frame.setContentPane(crPanel);
		frame.validate();
		frame.setVisible(true);	// must come BEFORE init, so that getSize() works
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		int extras= chroma;
		System.err.println("enter chromatic number, maxISsize: ");
		String prefix= "";
		String suffix= ".gpack";
		String gfld= prefix + pname + suffix;
		Graph gr= null;
		switch(type) {
		case 1: gr= MatrixGraph.create(new File(fname)); break;
		case 2: gr= RingChordGraph.create(frame); break;
		case 3: gr= PrefAttachGraph.create(frame); break;
		case 4: gr= Library.getPack(frame).graph; break;
			}
		GraphPack gp= null;
		if (gr!=null) {
			System.err.println("will build GraphPack, extras="+ extras);
			gp= new GraphPack(gr,"creation model: "+type);
//			gp.properties.setProperty("chromaticNumber",""+chroma);
//			gp.properties.setProperty("maxISsize",""+maxISsize);
			gp.properties.setProperty("graphletType","local nodes, edges, nhbr edges, degrees");
			buildLayouts(gp,crPanel,extras); 
			Library.putPack(frame,gp, new File(gfld));
			System.err.println("saved game at "+ gfld);
			}
		else System.err.println("FAILED to construct graphpack ");
		}
		
	private void buildLayouts(GraphPack gp, Creator crPanel, int extras) {
		try {
			crPanel.init(gp.graph);
			System.err.println("GraphPack inited crPanel");
			synchronized(crPanel) { crPanel.wait();	}	// Creator's "next" button will kick this
			System.err.println("graphPack entering graphlet loop. extras="+ extras);
			Enumeration<Node> enNodes= gp.graph.enumNodes();
//			for (int i=0; i<graph.numNodes(); i++) {
			while (enNodes.hasMoreElements()) {
				Node node= enNodes.nextElement();
				Graph graphlet= gp.graph.makeGraphlet(node,extras);
				crPanel.init(graphlet);
				graphlet.prettyPrint(System.err);
				synchronized(crPanel) { crPanel.wait(); }// Creator's "next" button will kick this
				gp.graphlets[node.getIndex()]= graphlet;
				}
			}
		catch(InterruptedException ie) {}
		}
	
	/** The main driver; invoke this from the command line to start the process. 
		Supply it with 2 arguments: the chromatic number of the graph (arrrg??!!)
		and the maximum Independent Set size (arrrrgh??!!)
		TODO: These parameters are anachronisms; things like chromatic number
		should be entered into the Properties field of the Graph or GraphPack.
		*/
	public static void main(String[] args) { 
		if (args.length==0) {
			System.err.println("argument must be the name of a .matrix file");
			System.exit(01);
			}
		String fname= args[0];
		File f= new File(fname);
		if (!f.exists()) {
			System.err.println("argument must be the name of a .matrix file");
			System.exit(02);
			}
		//set the default flags
		int flags = args.length<2 ? 0 : Integer.parseInt(args[1]);

//		int chroma= Integer.parseInt(args[1]);
//		int maxISs= Integer.parseInt(args[2]);
//		String pname= args[3];
//		new GraphPackBuilder(fname,chroma,maxISs); 
		new GraphPackBuilder(fname,flags,0); 
		System.exit(0);
		}
	
	} // EOClass GraphPackBuilder
